package kr.ac.kaist.idb.csnql.clause;

import java.io.Serializable;

/**
 * @brief EVENT LISTEN clause
 * @author Jongheon Park (korex527@kaist.ac.kr)
 *
 */
public class SNQLEvent implements Serializable
{
	
	/**
	 * @brief Serial version UID which is automatically generated
	 */
	private static final long serialVersionUID = -326024044352234343L;

	/**
	 * @brief true, if there is no pre-defined event in the clause
	 */
	private Boolean instantEvent;
	
	/**
	 * @brief Event name
	 */
	private String eventname_;
	
	/**
	 * @brief Triggering condition predicate
	 */
	private SNQLExpression triggering_predicate;
	
	/** 
	 * @brief Event listening period 
	 * */
	private long listening_period;
	
	/** 
	 * @brief Event listening_duration. 
	 * */
	private long listening_duration;
	
	/** 
	 * @brief ONCE/REPEAT flag 
	 */
	private Boolean justOnce;
	
	/** 
	 * @brief true, if period is blank 
	 */
	private Boolean frequentPeriod;
	
	/** 
	 * @brief true, if duration is blank 
	 */
	private Boolean infiniteDuration;
	
	/**
	 * @brief Instantiates a new SNQLEvent.
	 */
	public SNQLEvent()
	{
		instantEvent = true;
		justOnce = true;
		frequentPeriod = false;
		infiniteDuration = false;
		triggering_predicate = new SNQLExpression();
		eventname_= new String();
		listening_period = -1;
		listening_duration = -1;
	}
	
	/**
	 * @brief Check if there is no pre-defined event in the clause
	 * @return true, if there is no pre-defined event in the clause
	 */
	public Boolean getInstantEvent() {
		return instantEvent;
	}
	
	/**
	 * @param instantEvent instantEvent flag
	 * @brief Set the instantEvent
	 */
	public void setInstantEvent(Boolean instantEvent) {
		this.instantEvent = instantEvent;
	}

	/**
	 * @return true, if this has ONCE, otherwise false
	 * @brief Check whether this clause is ONCE/REPEAT
	 */
	public Boolean getJustOnce() {
		return justOnce;
	}

	/**
	 * @param justOnce ONCE/REPEAT flag
	 * @brief Set the ONCE/REPEAT flag
	 */
	public void setJustOnce(Boolean justOnce) {
		this.justOnce = justOnce;
	}

	/**
	 * @return the event name
	 * @brief Get the event name
	 */
	public String getEventname_() {
		return eventname_;
	}

	/**
	 * @param eventname_ New event name
	 * @brief Set the event name
	 */
	public void setEventname_(String eventname_) {
		this.eventname_ = eventname_.substring(1, eventname_.length()-1);
	}

	/**
	 * @return the triggering_predicate
	 * @brief Get the triggering_predicate
	 */
	public SNQLExpression getTriggering_predicate() {
		return triggering_predicate;
	}

	/**
	 * @param triggering_predicate New triggering_predicate
	 * @brief Set the triggering_predicate
	 */
	public void setTriggering_predicate(SNQLExp triggering_predicate) {
		this.triggering_predicate = (SNQLExpression) triggering_predicate;
	}

	/**
	 * @return the listening_period
	 * @brief Get the listening_period
	 */
	public long getListening_period() {
		return listening_period;
	}

	/**
	 * @param listening_period New period from string
	 * @brief Set the period from string
	 */
	public void setPeriodFromString(String listening_period) {
		this.listening_period = SNQLUtils.getTimeToLong(listening_period); 
	}
	
	/**
	 * @param period New listening_period
	 * @brief Set the listening_period
	 */
	public void setListening_period(long period)
	{
		this.listening_period = period;
	}

	/**
	 * @return the listening_duration
	 * @brief Get the listening_duration
	 */
	public long getListening_duration() {
		return listening_duration;
	}

	/**
	 * @param listening_duration New duration from string
	 * @brief Set the duration from string
	 */
	public void setDurationFromString(String listening_duration) {
		long temp = SNQLUtils.getTimeToLong(listening_duration);
		
		if(this.listening_period >= 0 & temp < this.listening_period)
			this.listening_duration = this.listening_period;
		else
			this.listening_duration = temp;
	}
	
	/**
	 * @param duration New listening_duration
	 * @brief Set the listening_duration
	 */
	public void setListening_duration(long duration)
	{
		this.listening_duration = duration;
	}
	
	/**
	 * @brief Check whehter period is blank
	 * @return true, if period is blank
	 */
	public Boolean getFrequentPeriod() {
		return frequentPeriod;
	}

	/**
	 * @param frequentPeriod frequentPeriod flag
	 * @brief Set whether period is frequent or not
	 */
	public void setFrequentPeriod(Boolean frequentPeriod) {
		this.frequentPeriod = frequentPeriod;
	}

	/**
	 * @brief Check whehter duration is blank
	 * @return true, if duration is blank
	 */
	public Boolean getInfiniteDuration() {
		return infiniteDuration;
	}

	/**
	 * @param infiniteDuration infiniteDuration flag
	 * @brief Set whether duration is infinite or not
	 */
	public void setInfiniteDuration(Boolean infiniteDuration) {
		this.infiniteDuration = infiniteDuration;
	}

	/**
	 * @param str ONCE/REPEAT
	 * @brief Set ONCE/REPEAT from string
	 */
	public void setOnceFromString(String str) {
		if(str.compareTo("ONCE") == 0)
			this.justOnce = true;
		else if(str.compareTo("REPEAT") == 0)
			this.justOnce = false;
		else
			this.justOnce = true;
	}
	public String toString()
	{
		StringBuffer stringbuffer = new StringBuffer();

		stringbuffer.append("(");
		
		if(instantEvent)
			stringbuffer.append(triggering_predicate.toString());
		else
			stringbuffer.append("\"" + eventname_ + "\"");
	
		if(frequentPeriod)
			stringbuffer.append(", " + "FREQUENT");
		else
			stringbuffer.append(", " + listening_period);
		
		if(infiniteDuration)
			stringbuffer.append(", " + "INFINITE");
		else
			stringbuffer.append(", " + listening_duration);
		
		if(justOnce)
			stringbuffer.append(", " + "ONCE)");
		else
			stringbuffer.append(", " + "REPEAT)");
		
		return stringbuffer.toString();
	}
}
